package com.springapp.mvc.config;

import com.springapp.mvc.services.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.authentication.dao.ReflectionSaltSource;
import org.springframework.security.authentication.dao.SaltSource;
import org.springframework.security.authentication.encoding.PasswordEncoder;
import org.springframework.security.authentication.encoding.ShaPasswordEncoder;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;


/**
 * Created by dbychkov on 12.01.2015.
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Autowired
    public void configure(AuthenticationManagerBuilder auth) throws Exception{
        auth.authenticationProvider(daoAuthenticationProvider());
    }

    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider() throws Exception{
        DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
        daoAuthenticationProvider.setUserDetailsService(userService);
        daoAuthenticationProvider.setSaltSource(saltSource());
        daoAuthenticationProvider.setPasswordEncoder(sha256Encoder());
        return daoAuthenticationProvider;
    }

    @Override
    public void configure(WebSecurity web) throws Exception {
        web
            .ignoring()
            .antMatchers("/resources/**");
    }

    @Bean
    public PasswordEncoder sha256Encoder(){
        return new ShaPasswordEncoder(256);
    }

    @Bean
    public SaltSource saltSource() throws Exception {
        ReflectionSaltSource saltSource = new ReflectionSaltSource();
        saltSource.setUserPropertyToUse("username");
        return saltSource;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http
             .headers()
                 .disable()
             .csrf()
                 .disable()
             .requiresChannel()
                 .antMatchers("/login_page*",
                              "/user/**",
                              "/admin/**",
                              "/supervisor/**")
                 .requiresSecure()
                .and()
             .formLogin()
                 .loginPage("/login_page")
                 .defaultSuccessUrl("/")
                 .failureUrl("/")
                 .usernameParameter("username")
                 .passwordParameter("password")
                .and()
                .logout()
                 .logoutUrl("/logout_page")
                 .logoutSuccessUrl("/")
                 .permitAll()
                 .deleteCookies("JSESSIONID")
                .and()
            .authorizeRequests()
                 .antMatchers("/user/**").hasAuthority("ROLE_USER")
                 .antMatchers("/admin/**").hasAuthority("ROLE_ADMIN")
                 .antMatchers("/supervisor/**").hasAuthority("ROLE_SUPERVISOR");
    }
}
